package com.github.xzb617.client.flow.core;

import com.github.xzb617.client.flow.core.hotparam.HotParamRule;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 流量控制配置属性
 * @author xzb617
 */
@RefreshScope
@Component
@ConfigurationProperties(prefix = "goalkeeper.flow")
public class FlowProperties {

    private SystemProtectedProperties system = new SystemProtectedProperties();

    private HotParamProperties param = new HotParamProperties();

    private RulesProperties rules = new RulesProperties();

    private RejectProperties reject = new RejectProperties();

    /**
     * 系统保护限流配置属性
     */
    public class SystemProtectedProperties {

        private Boolean enabled = true;

        private Map<String, Integer> rules = new HashMap<>(3);

        public Boolean getEnabled() {
            return enabled;
        }

        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }

        public Map<String, Integer> getRules() {
            return rules;
        }

        public void setRules(Map<String, Integer> rules) {
            this.rules = rules;
        }

        @Override
        public String toString() {
            return "SystemProtectedProperties{" +
                    "enabled=" + enabled +
                    ", rules=" + rules +
                    '}';
        }
    }

    /**
     * 热点参数限流配置属性
     */
    public class HotParamProperties {

        private Boolean enabled = true;

        private Map<String, Map<String, Object>> rules = new HashMap<>();

        public Boolean getEnabled() {
            return enabled;
        }

        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }

        public Map<String, Map<String, Object>> getRules() {
            return rules;
        }

        public void setRules(Map<String, Map<String, Object>> rules) {
            this.rules = rules;
        }

        @Override
        public String toString() {
            return "HotParamProperties{" +
                    "enabled=" + enabled +
                    ", rules=" + rules +
                    '}';
        }
    }

    /**
     * 规则限流配置属性
     */
    public class RulesProperties {

        private Boolean enabled = true;

        private String supportRule = "IP,URL";

        /**
         * 默认支持类型： IP,URI
         */
        private Map<String, Map<String, Integer>> limits = new HashMap<>(6);

        public Boolean getEnabled() {
            return enabled;
        }

        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }

        public String getSupportRule() {
            return supportRule;
        }

        public void setSupportRule(String supportRule) {
            this.supportRule = supportRule;
        }

        public Map<String, Map<String, Integer>> getLimits() {
            return limits;
        }

        public void setLimits(Map<String, Map<String, Integer>> limits) {
            this.limits = limits;
        }

        @Override
        public String toString() {
            return "RulesProperties{" +
                    "enabled=" + enabled +
                    ", supportRule='" + supportRule + '\'' +
                    ", limits=" + limits +
                    '}';
        }
    }

    /**
     * 拒绝策略
     */
    public class RejectProperties {
        /**
         * 策略有：
         * 1.快速失败 QUICK_FAIL, 暂无其它
         */
        private String strategy = "QUICK_FAIL";

        /**
         * 响应状态，默认：429
         */
        private Integer responseStatus = HttpStatus.TOO_MANY_REQUESTS.value();

        /**
         * 响应内容： 默认： {"code": 429, "message": "触发限流，拒绝访问"}
         */
        private String responseContent = "Blocking by GoalKeeper";

        public String getStrategy() {
            return strategy;
        }

        public void setStrategy(String strategy) {
            this.strategy = strategy;
        }

        public Integer getResponseStatus() {
            return responseStatus;
        }

        public void setResponseStatus(Integer responseStatus) {
            this.responseStatus = responseStatus;
        }

        public String getResponseContent() {
            return responseContent;
        }

        public void setResponseContent(String responseContent) {
            this.responseContent = responseContent;
        }

        @Override
        public String toString() {
            return "RejectProperties{" +
                    "strategy='" + strategy + '\'' +
                    ", responseStatus=" + responseStatus +
                    ", responseContent='" + responseContent + '\'' +
                    '}';
        }
    }






    public SystemProtectedProperties getSystem() {
        return system;
    }

    public void setSystem(SystemProtectedProperties system) {
        this.system = system;
    }

    public HotParamProperties getParam() {
        return param;
    }

    public void setParam(HotParamProperties param) {
        this.param = param;
    }

    public RulesProperties getRules() {
        return rules;
    }

    public void setRules(RulesProperties rules) {
        this.rules = rules;
    }

    public RejectProperties getReject() {
        return reject;
    }

    public void setReject(RejectProperties reject) {
        this.reject = reject;
    }

    @Override
    public String toString() {
        return "FlowProperties{" +
                "system=" + system.toString() +
                ", rules=" + rules.toString() +
                ", reject=" + reject.toString() +
                ", param=" + param.toString() +
                '}';
    }
}
